package com.hemerasolutions.v2trainer.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hemerasolutions.v2trainer.dao.*;
import com.hemerasolutions.v2trainer.dao.interfaces.AcademyDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.AdminDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.AthleteDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.EquipmentDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.LibraryDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.PersonalTrainerDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.PhotoDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.RoleDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.TeacherDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.ThemeDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.TrainingTypeDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.UserDaoInterface;
import com.hemerasolutions.v2trainer.dao.interfaces.VideoDaoInterface;
import com.hemerasolutions.v2trainer.model.exercise.Equipment;
import com.hemerasolutions.v2trainer.model.library.Library;
import com.hemerasolutions.v2trainer.model.multimedia.Photo;
import com.hemerasolutions.v2trainer.model.multimedia.Video;
import com.hemerasolutions.v2trainer.model.others.Theme;
import com.hemerasolutions.v2trainer.model.security.AccessRole;
import com.hemerasolutions.v2trainer.model.training.TrainingType;
import com.hemerasolutions.v2trainer.model.users.Academy;
import com.hemerasolutions.v2trainer.model.users.Admin;
import com.hemerasolutions.v2trainer.model.users.Athlete;
import com.hemerasolutions.v2trainer.model.users.PersonalTrainer;
import com.hemerasolutions.v2trainer.model.users.Teacher;
import com.hemerasolutions.v2trainer.model.users.User;
import com.hemerasolutions.v2trainer.service.interfaces.UserServiceInterface;

@Service("userService")
public class UserService extends BaseService implements UserServiceInterface {

	private static final long serialVersionUID = 1L;
	
	@Autowired
	private UserDaoInterface userDao;
	
	@Autowired
	private AdminDaoInterface adminDao;
	
	@Autowired
	private AcademyDaoInterface academyDao;

	@Autowired
	private RoleDaoInterface roleDao;
	
	@Autowired 
	private EquipmentDaoInterface equipmentDao;
	
	@Autowired
	private AthleteDaoInterface athleteDao;

	@Autowired
	private PersonalTrainerDaoInterface ptDao;

	@Autowired
	private TeacherDaoInterface teacherDao;

	@Autowired
	private PhotoDaoInterface photoDao;

	@Autowired
	private VideoDaoInterface videoDao;    
	
	@Autowired
	private LibraryDaoInterface libraryDao;
	
	@Autowired
	private ThemeDaoInterface themeDao;
	
	@Autowired
	private TrainingTypeDaoInterface ttDao; 
	

	
	
	public UserService() {
		super();
	}

	
	@Override
	public Photo copyDefaultLogo(){
		
		return new Photo(photoDao.findByLocation("default_logo.jpg"));
	}
	
	@Override
	public Photo copyDefaultWideLogo(){
		return new Photo(photoDao.findByLocation("default_logo_wide.jpg"));
	}
	
	@Override
	public Photo copyDefaultUserPhoto(){
		return new Photo(photoDao.findByLocation("user_photo.jpg"));
	}
	
	
	
	@Override
	public Photo readDefaultLogo(){
		return photoDao.findByLocation("default_logo.jpg");
	}
	
	@Override
	public Photo readDefaultWideLogo(){
		return photoDao.findByLocation("default_logo_wide.jpg");
	}
	
	@Override
	public Photo readDefaultUserPhoto(){
		return photoDao.findByLocation("user_photo.jpg");
	}



	
	
	
	
	
	@Override
	public Library readUserLibrary(String userName){
		return null;
		
	}
	

	@Override
	public Academy createAcademy(Academy academy) throws ExceptionService {

			try {

				academy.getUser().setUserType(User.USERTYPE_ACADEMY);
				academy.getUser().getRoles().add(this.readRole("ROLE_ACADEMY"));
				academy.setUser(this.saveUser(academy.getUser()));
				academy.setTeachers(this.createTeacher(academy.getTeachers()));
				
				academyDao.create(academy);

			} catch (ExceptionDao e) {
				throw new ExceptionService(e);
			} catch (ExceptionService e) {
				throw e;
			}
		
		return academy;

	}

	
	private AccessRole readRole(String role) {

		return roleDao.getByName(role);
		
	}



	@Override
	public List<Academy> searchAcademys (Map<String,Object> fields){

		return academyDao.search(fields);
		
	}
	
	@Override
	public List<Teacher> createTeacher(List<Teacher> teachers) throws ExceptionService {
		try {
			return teacherDao.create(teachers);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}
	}


	

	@Override
	public Academy saveAcademy(Academy academy) throws ExceptionService{

		try {
			academyDao.save(academy);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		} catch (ExceptionService e) {
			throw e;
		}
	
	return academy;	
	}

	@Override
	public void deleteAcademy(Academy academy) throws ExceptionService{
		try {
			academyDao.delete(academy);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}			
		
	}

	@Override
	public Academy readAcademy(Academy academy) throws ExceptionService {
		return academyDao.getById(academy.getId());
	}
	
	
	@Override
	public User saveUser(User user) throws ExceptionService {
		try{
			return userDao.save(user);
		} catch (ExceptionDao e) {
			throw new ExceptionService(e.getLocalizedMessage());
		} catch (ExceptionService e) {
			throw e;
		}
		
		
	}

	
	@Override
	public Photo savePhoto(Photo photo) throws ExceptionService{
		if(photo != null){
			return photoDao.save(photo);
		}else{
			return photo;
		}
	}

	@Override
	public List<Photo> savePhoto(List<Photo> photos) throws ExceptionService {
		if(photos != null && !photos.isEmpty()){
			return photoDao.save(photos);
		}else{
			return photos;
		}
	}
	

	@Override
	public Video saveVideo(Video video) throws ExceptionService {
		if(video != null){
			return videoDao.save(video);
		}else{
			return video;
		}
	}

	@Override
	public List<Video> saveVideo(List<Video> videos) throws ExceptionService{
		if(videos != null && !videos.isEmpty()){
			return videoDao.save(videos);
		}else{
			return videos;
		}
	}

	
	@Override
	public User createUser(User user) throws ExceptionService{
		return userDao.create(user);
	}

	@Override
	public User readUser(User user) throws ExceptionService {
		return userDao.getById(user.getId());
	}
	
	@Override
	public void deleteUser(User user) throws ExceptionService {
		userDao.delete(user);
	}


	@Override
	public List<Theme> listThemes() throws ExceptionService  {

		return this.themeDao.list();

	}


	@Override
	public List<Equipment> searchAcademyEquipments(Map<String, Object> fields) {
		return equipmentDao.searchEquipmentsOfAcademy(fields);

	}

	@Override
	public List<TrainingType> listTrainingType(){
		
		return ttDao.list();
		
	}



	@Override
	public User getUserByUserEmail(String userName) {
		return userDao.findByUserName(userName);
	}



	@Override
	public PersonalTrainer createPersonalTrainer(PersonalTrainer personalTrainer) {
		try {

			personalTrainer.getUser().setUserType(User.USERTYPE_PT);
			personalTrainer.getUser().getRoles().add(this.readRole("ROLE_PERSONAL"));
			personalTrainer.setUser(this.saveUser(personalTrainer.getUser()));
			ptDao.create(personalTrainer);

		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		} catch (ExceptionService e) {
			throw e;
		}
	
		return personalTrainer;
		
	}



	@Override
	public  PersonalTrainer savePersonalTrainer(PersonalTrainer personalTrainer) {

		try {
				ptDao.save(personalTrainer);
			} catch (ExceptionDao e) {
				e.printStackTrace();
				throw new ExceptionService(e);
			} catch (ExceptionService e) {
				throw e;
			}
		
		return personalTrainer;	
		
	}



	@Override
	public  PersonalTrainer readPersonalTrainer(PersonalTrainer personalTrainer) {
		return ptDao.getById(personalTrainer.getId());
	}



	@Override
	public List<PersonalTrainer> searchPersonalTrainers(
			Map<String, Object> fields) {
		return ptDao.search(fields);
	}



	@Override
	public void deletePersonalTrainer(PersonalTrainer personalTrainer) {
		try {
			ptDao.delete(personalTrainer);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}			
		
	}



	@Override
	public Teacher saveTeacher(Teacher teacher) {

		try {
				teacherDao.save(teacher);
			} catch (ExceptionDao e) {
				e.printStackTrace();
				throw new ExceptionService(e);
			} catch (ExceptionService e) {
				throw e;
			}
		
		return teacher;	
		
	}

	@Override
	public Teacher createTeacher(Teacher teacher) throws ExceptionService {
		try {
			teacher.getUser().setUserType(User.USERTYPE_TEACHER);
			teacher.getUser().getRoles().add(this.readRole("ROLE_TEACHER"));
			teacher.setUser(this.saveUser(teacher.getUser()));

			return teacherDao.create(teacher);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}
	}


	@Override
	public Teacher readTeacher(Teacher teacher) {
		return teacherDao.getById(teacher.getId());
	}



	@Override
	public List<Teacher> searchTeachers(Map<String, Object> fields) {
		return teacherDao.search(fields);
	}



	@Override
	public void deleteTeacher(Teacher teacher) {
		try {
			teacherDao.delete(teacher);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}	
		
	}



	@Override
	public Athlete saveAthlete(Athlete athlete) throws ExceptionService {
		try {
			return athleteDao.save(athlete);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		} catch (ExceptionService e) {
			throw e;
		}
	}



	@Override
	public Athlete createAthlete(Athlete athlete) throws ExceptionService {
		try {
			athlete.getUser().setUserType(User.USERTYPE_ATHLETE);
			athlete.getUser().getRoles().add(this.readRole("ROLE_ATHLETE"));
			athlete.setUser(this.saveUser(athlete.getUser()));
			athleteDao.create(athlete);

		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		} catch (ExceptionService e) {
			throw e;
		}
	
		return athlete;
	}



	@Override
	public void deleteAthlete(Athlete athlete) throws ExceptionService {
		try {
			
			athleteDao.delete(athlete);

		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		} catch (ExceptionService e) {
			throw e;
		}
	
		
	}



	@Override
	public Athlete readAthlete(Athlete athlete) {
		return this.athleteDao.getById(athlete.getId());
	}



	@Override
	public List<Athlete> searchAthletes(Map<String, Object> fields) {
		return athleteDao.search(fields);

	}



	@Override
	public boolean sendPassword(User userByUserName) {
		// TODO Auto-generated method stub
		return false;
	}



	@Override
	public Admin createAdmin(Admin admin) {

		try{
			admin.getUser().setUserType(User.USERTYPE_ADMIN);
			admin.getUser().getRoles().add(this.readRole("ROLE_ADMIN"));
			admin.setUser(this.saveUser(admin.getUser()));

			return adminDao.create(admin);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}
	}



	@Override
	public Admin saveAdmin(Admin admin) {
		try {
			return adminDao.save(admin);
		} catch (ExceptionDao e) {
			throw new ExceptionService(e.getLocalizedMessage());
		} catch (ExceptionService e) {
			throw e;
		}
		
	}



	@Override
	public Admin readAdmin(Admin admin) {
		return adminDao.getById(admin.getId());
	}



	@Override
	public void deleteAdmin(Admin admin) {
		try {
			adminDao.delete(admin);
		} catch (ExceptionDao e) {
			e.printStackTrace();
			throw new ExceptionService(e);
		}			

		
	}

	@Override
	public List<Admin> searchAdmins(Map<String, Object> fields) {
		return adminDao.search(fields);
	}

	public <T> T getActiveUser(User user, Class<T> type){
		return this.userDao.getActiveUser(user,type);
	}


}


